public class Vector2f {
	public float x;
	public float y;
	
	public Vector2f() {
		this(0, 0);
	}
	
	public Vector2f(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public Vector2f(Vector2f other) {
		if (other == null)
			throw new IllegalArgumentException();

		x = other.x;
		y = other.y;
	}

	public float length() {
		return (float)Math.sqrt(x * x + y * y);
	}

	public float dot(Vector2f other) {
		if (other == null)
			throw new IllegalArgumentException();
		
		return x * other.x + y * other.y;
	}
	
	/** Determines the distance from the point represented by this vector to
	 * a line from a to b. Uses math from http://www.faqs.org/faqs/graphics/algorithms-faq/
	 */
	public float distanceToLine(Vector2f a, Vector2f b) {
		return Math.abs((a.y-y)*(b.x-a.x)-(a.x-x)*(b.y-a.y)) /
				(float) Math.sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
	}
	
	/**
	 * Finds two values representing the intersection of two lines such that if
	 * ab and cd intersect, then both returned values are between 0 and 1
	 * inclusive, and if r=returned[0], then the intersection is a + (r * ab).
	 * Uses math from http://www.faqs.org/faqs/graphics/algorithms-faq/
	 * 	Section 1.03
	 */
	public static float[] findIntersection(Vector2f a, Vector2f b, Vector2f c,
			Vector2f d) {
		float denom = (b.x - a.x) * (d.y - c.y) - (b.y - a.y) * (d.x - c.x);
		if (denom == 0) //parallel
			return new float[] {Float.MAX_VALUE, Float.MAX_VALUE};
		float r = ((a.y - c.y) * (d.x - c.x) - (a.x - c.x) * (d.y - c.y))
				/ denom;
		float s = ((a.y - c.y) * (b.x - a.x) - (a.x - c.x) * (b.y - a.y))
				/ denom;
		return new float[] { r, s };
	}

	// Fake cross product Z component
	public float cross(Vector2f other) {
		return x * other.y - other.x * y;
	}
	
	/** 
	 * Finds the cross product of (a-this) X (b - a).
	 * This value is positive if b is to the left of the line this-to-a.
	 **/
	public float cross(Vector2f a, Vector2f b) {
		return x*(a.y-b.y) + a.x*(b.y-y) + b.x*(y-a.y);
	}

	public void sum(Vector2f other) {
		if (other == null)
			throw new IllegalArgumentException();
		
		x += other.x;
		y += other.y;
	}
	
	public void scale(float s) {
		x *= s;
		y *= s;
	}
	
	public void sumScale(Vector2f other, float s) {
		if (other == null)
			throw new IllegalArgumentException();
		
		x += other.x * s;
		y += other.y * s;
	}
	
	public void normalize() {
		float length = length();
		if (length == 0)
			throw new IllegalStateException();
		
		scale(1 / length);
	}
	
	public String toString() {
		return "(" + x + "," + y + ")";
	}
}
